//---------------------------------------------------------------------------
// Sword3 Engine (c) 1999-2000 by Kingsoft
//
// File:	Event.cpp
// Date:	2000.08.08
// Code:	WangWei(Daphnis)
// Desc:	Implements a simple event object for thread synchronization
//---------------------------------------------------------------------------
#include "KRuntime.h"
#include "KTrace.h"
#include "KInterlock.h"
#include "KSyncObj.h"

namespace krt
{
	namespace sync
	{

#ifdef _WINDOWS

		CriticalSection::CriticalSection()
		{
			::InitializeCriticalSection(&m_cs);
		}

#if (_WIN32_WINNT >= 0x0403)
		CriticalSection::CriticalSection(DWORD SpinCount)
		{
			::InitializeCriticalSectionAndSpinCount(&m_cs, SpinCount);
		}
#endif

		CriticalSection::~CriticalSection()
		{
			::DeleteCriticalSection(&m_cs);
		}

		void CriticalSection::enter()
		{
			::EnterCriticalSection(&m_cs);
		}

		BOOL CriticalSection::TryEnter(DWORD TimeoutMillis)
		{
			return (FALSE != ::TryEnterCriticalSection(&m_cs));
		}

		void CriticalSection::leave()
		{
			::LeaveCriticalSection(&m_cs);
		}


		Event::Event()
		{
			m_hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
		}

		Event::~Event()
		{
			::CloseHandle(m_hEvent);
		}

		void Event::set()
		{
			::SetEvent(m_hEvent);
		}

		void Event::reset()
		{
			::ResetEvent(m_hEvent);
		}

		void Event::wait()
		{
			::WaitForSingleObject(m_hEvent, INFINITE);
		}

		BOOL Event::wait(DWORD TimeoutMillis)
		{
			return (WAIT_OBJECT_0 == ::WaitForSingleObject(m_hEvent, TimeoutMillis));
		}


		WinSemaphore::WinSemaphore()
		{
			m_hSemaphore = ::CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
			assert(NULL != m_hSemaphore);
		}

		WinSemaphore::~WinSemaphore()
		{
			::CloseHandle(m_hSemaphore);
		}

		void WinSemaphore::wait()
		{
			::WaitForSingleObject(m_hSemaphore, INFINITE);
		}

		BOOL WinSemaphore::wait(DWORD TimeoutMillis)
		{
			return (WAIT_OBJECT_0 == ::WaitForSingleObject(m_hSemaphore, TimeoutMillis)); 
		}

		void WinSemaphore::release(LONG ReleaseCount)
		{
			::ReleaseSemaphore(m_hSemaphore, ReleaseCount, NULL);
		}

#endif

		void DeadLoopLock::enter()
		{
			while (0 != LockExchange(&m_state, 1));
		}

		BOOL DeadLoopLock::TryEnter(DWORD TimeoutMillis)
		{
			return (0 == LockExchange(&m_state, 1));
		}

		void DeadLoopLock::leave()
		{
			LockExchange(&m_state, 0);
		}

	}
}